package com.yanqu.road.server.gameplayer.module.vehicle;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.config.patrons.CombSkillUnlockInfo;
import com.yanqu.road.entity.config.patrons.PatronsInfo;
import com.yanqu.road.entity.config.skill.SkillInfo;
import com.yanqu.road.entity.config.skill.SkillUpgradeInfo;
import com.yanqu.road.entity.config.vehicle.*;
import com.yanqu.road.entity.cricket.CricketData;
import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.log.*;
import com.yanqu.road.entity.manor.FishData;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.entity.task.args.VehicleArgs;
import com.yanqu.road.entity.task.args.union.UnionActivityTaskArgs;
import com.yanqu.road.logic.bussiness.player.UserPasswordBussiness;
import com.yanqu.road.logic.bussiness.player.UserVehicleBussiness;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.VehiclePb;
import com.yanqu.road.pb.vehicle.VehicleProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.cricket.CricketMgr;
import com.yanqu.road.server.gameplayer.module.cricket.CricketModule;
import com.yanqu.road.server.gameplayer.module.manor.ManorFishPondModel;
import com.yanqu.road.server.gameplayer.module.manor.ManorModule;
import com.yanqu.road.server.gameplayer.module.patrons.PatronsModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.ConfigMgr;
import com.yanqu.road.server.manger.DataAnalyticsMgr;
import com.yanqu.road.server.manger.ForbiddenWordMgr;
import com.yanqu.road.server.manger.activity.NormalActivityMgr;
import com.yanqu.road.server.manger.activity.curio.CurioMgr;
import com.yanqu.road.server.manger.activity.strongholdwar.StrongholdActivityMgr;
import com.yanqu.road.server.manger.activity.unionwar.UnionPhaseWarMgr;
import com.yanqu.road.server.manger.config.*;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.manor.FishPondMgr;
import com.yanqu.road.server.manger.player.WorldMessageMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.UUIDHelper;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class VehicleModule extends GeneralModule {

    private Map<String, UserVehicle> userVehicleMap;

    private UserVehicleDetail userVehicleDetail;

    private Map<String, PatronsVehicleBindingData> patronsVehicleBindingDataMap = new ConcurrentHashMap<>();

    private PlayerVehicleAutoModifyCost playerVehicleAutoModifyCost = new PlayerVehicleAutoModifyCost();

    private UserPassword userPassword;

    private final List<String> recycleVehicleUIDs = new ArrayList<>(); // 待自动回收的珍兽列表

    public VehicleModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean saveData() {
        if (null != userVehicleDetail) {
            if (userVehicleDetail.isInsertOption()) {
                UserVehicleBussiness.addUserVehicleDetail(userVehicleDetail);
            } else if (userVehicleDetail.isUpdateOption()) {
                UserVehicleBussiness.updateUserVehicleDetail(userVehicleDetail);
            }
        }
        if (null != userVehicleMap) {
            for (UserVehicle userVehicle : userVehicleMap.values()) {
                if (userVehicle.isUpdateOption()) {
                    UserVehicleBussiness.updateUserVehicle(userVehicle);
                } else if (userVehicle.isInsertOption()) {
                    UserVehicleBussiness.addUserVehicle(userVehicle);
                }
                if (null != userVehicle.getSkillMap()) {
                    for (UserVehicleSkill vehicleSkill : userVehicle.getSkillMap().values()) {
                        if (vehicleSkill.isInsertOption()) {
                            UserVehicleBussiness.addUserVehicleSkill(vehicleSkill);
                        } else if (vehicleSkill.isUpdateOption()) {
                            UserVehicleBussiness.updateUserVehicleSkill(vehicleSkill);
                        }
                    }
                }
                if (null != userVehicle.getOtherSkillList()) {
                    for (UserVehicleOtherSkill otherSkill : new ArrayList<>(userVehicle.getOtherSkillList())) {
                        if (otherSkill.isInsertOption()) {
                            UserVehicleBussiness.addUserVehicleOtherSkill(otherSkill);
                        } else if (otherSkill.isUpdateOption()) {
                            UserVehicleBussiness.updateUserVehicleOtherSkill(otherSkill);
                        }
                    }
                }
            }
        }
        if (patronsVehicleBindingDataMap != null) {
            for (PatronsVehicleBindingData data : new ArrayList<>(patronsVehicleBindingDataMap.values())) {
                if (data.isInsertOption()) {
                    UserVehicleBussiness.addPatronsVehicleBindingData(data);
                } else if (data.isUpdateOption()) {
                    UserVehicleBussiness.aupdatePatronsVehicleBindingData(data);
                }
            }
        }

        if (null != userPassword) {
            if (userPassword.isInsertOption()) {
                UserPasswordBussiness.addUserPassword(userPassword);
            } else if (userPassword.isUpdateOption()) {
                UserPasswordBussiness.updateUserPassword(userPassword);
            }
        }

        return true;
    }

    public void addPatronsBindData(int activityId, int patronsId, String vehicleId) {
        PatronsVehicleBindingData data = patronsVehicleBindingDataMap.get(vehicleId);
        if (data == null) {
            data = new PatronsVehicleBindingData();
            data.setVehicleId(vehicleId);
            data.setInsertOption();
            data.setUserId(getUserId());
            patronsVehicleBindingDataMap.put(vehicleId, data);
        }
        data.setPatronsId(patronsId);
        data.addActivityId(activityId);
        data.setLastUpdateTime(System.currentTimeMillis());

        syncPatronsBindMsg(Collections.singletonList(data));
    }

    public void addPatronsBindSystem(int systemId, int patronsId, String vehicleId, long endTime) {
        PatronsVehicleBindingData data = patronsVehicleBindingDataMap.get(vehicleId);
        if (data == null) {
            data = new PatronsVehicleBindingData();
            data.setVehicleId(vehicleId);
            data.setInsertOption();
            data.setUserId(getUserId());
            patronsVehicleBindingDataMap.put(vehicleId, data);
        }
        data.setPatronsId(patronsId);
        data.addSystem(systemId, endTime);
        data.setLastUpdateTime(System.currentTimeMillis());
        syncPatronsBindMsg(Collections.singletonList(data));
    }

    @Override
    public boolean loadData() {
        userVehicleDetail = UserVehicleBussiness.getUserVehicleDetail(player.getUserId());
        initUserVehicleDetail();
        userVehicleMap = UserVehicleBussiness.getUserVehicleAndSkillMap(player.getUserId());
        //修复技能错误信息
        for (UserVehicle userVehicle : userVehicleMap.values()) {
            VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
            initSkill(userVehicle, vehicleInfo);
        }
        patronsVehicleBindingDataMap = UserVehicleBussiness.getPatronsVehicleBindingData(player.getUserId());
        userPassword = UserPasswordBussiness.getUserPassWord(player.getUserId());
        return true;
    }

    @Override
    public boolean afterLoadData() {

        for (UserVehicle userVehicle : userVehicleMap.values()) {
            VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
            checkVehicleCombUnlock(userVehicle, vehicleInfo, false);
        }
        return true;
    }

    @Override
    public void loginSendMsg() {
        checkAndReset();
        checkSoulBlock();
        if (null != userVehicleMap) {
            syncVehicleData(new ArrayList<>(userVehicleMap.values()), true);
        }
        sendVehicleRecycleLock();
        syncLastResetVehicleTime();
    }



    private void syncPatronsBindMsg(Collection<PatronsVehicleBindingData> dataList) {
        VehicleProto.SyncPartonsVehicleBindingMsg.Builder syncMsg = VehicleProto.SyncPartonsVehicleBindingMsg.newBuilder();
        for (PatronsVehicleBindingData data : dataList) {
            VehicleProto.PartonsVehicleBindingMsg.Builder msg = VehicleProto.PartonsVehicleBindingMsg.newBuilder();
            msg.setPatronsId(data.getPatronsId());
            msg.setVehicleId(data.getVehicleId());
            msg.setActivityId(0);
            if (data.getActivityIdList().size() > 0) {
                msg.setActivityId(data.getActivityIdList().get(0));
            }
            if (data.getSystemId() > 0) {
                msg.setSystemId(data.getSystemId());
                msg.setSystemEndTime(data.getSystemEndTime());
            }
            syncMsg.addData(msg);
        }
        player.sendPacket(ClientProtocol.U_VEHICLE_ACTIVITY_PATRONS_BIND, syncMsg);
    }

    @Override
    public void afterLogin() {
        syncVehicleDetail();
        syncPatronsBindMsg(patronsVehicleBindingDataMap.values());
        // 排行榜刷新
        for (UserVehicle userVehicle : getBestRankVehicleMap().values()) {
            vehicleRankChange(userVehicle);
        }
    }

    private void initUserVehicleDetail() {
        if (null == userVehicleDetail) {
            UserVehicleDetail vehicleDetail = new UserVehicleDetail();
            vehicleDetail.setUserId(player.getUserId());
            vehicleDetail.setModifyTime(System.currentTimeMillis() / 1000);
            vehicleDetail.setInsertOption();
            userVehicleDetail = vehicleDetail;
        }
    }

    private void checkVehicleCombUnlock(UserVehicle userVehicle, VehicleInfo vehicleInfo, boolean isSendMsg) {
        List<UserVehicle> syncList = new ArrayList<>();
        VehicleComb vehicleComb = VehicleMgr.getVehicleComb(vehicleInfo.getCombId());
        if (null == vehicleComb) {
            return;
        }
        //组合珍兽变了，变成组合组合珍兽了(可以多个组合合并一个共同升级一个技能)
        List<Integer> combCombVehicleList = VehicleMgr.getCombCombVehicleList(vehicleInfo.getCombId());
        int combVehicleCount = 0;
        for (int vehicleId : combCombVehicleList) {
            if (null != getUserCombVehicle(vehicleId)) {
                combVehicleCount++;
            }
        }
        if (vehicleComb.getCombSkillId() > 0) {//有些组合就一个技能，不需要加
            UserVehicleOtherSkill combSkill = userVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), vehicleComb.getCombSkillId());
            if (null == combSkill) {
                combSkill = initVehicleOtherSkill(userVehicle, vehicleComb.getCombSkillId(), eVehicleSkillType.Comb.getValue(), combVehicleCount);
                userVehicle.getOtherSkillList().add(combSkill);
                syncList.add(userVehicle);
            } else {
                if (combSkill.getSkillLv() != combVehicleCount) {
                    combSkill.setSkillLv(combVehicleCount);
                    syncList.add(userVehicle);
                }
            }
        }
        for (int vehicleId : combCombVehicleList) {
            //处理自己的组合的技能，组合组合的技能不处理了吧
            UserVehicle userCombVehicle = getUserCombVehicle(vehicleId);
            if (null != userCombVehicle) {
                VehicleInfo combVehicleInfo = VehicleMgr.getVehicleInfo(userCombVehicle.getTemplateId());
                VehicleComb combVehicleComb = VehicleMgr.getVehicleComb(combVehicleInfo.getCombId());
                UserVehicleOtherSkill hasSkill = userCombVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), combVehicleComb.getCombSkillId());
                if (null != hasSkill && hasSkill.getSkillLv() != combVehicleCount) {
                    hasSkill.setSkillLv(combVehicleCount);
                    if (!syncList.contains(userCombVehicle)) {
                        syncList.add(userCombVehicle);
                    }
                }
            }
        }

        // 解锁珍兽自身光环
        for (Integer vehicleId : vehicleComb.getVehicleSelfSkillMap().keySet()) {
            UserVehicle userCombVehicle = getUserCombVehicle(vehicleId);
            if (userCombVehicle == null) {
                continue;
            }
            if (vehicleId == userVehicle.getTemplateId()) {
                List<Integer> skillIdList = vehicleComb.getVehicleSelfSkillMap().get(vehicleId);
                for (Integer skillId : skillIdList) {
                    UserVehicleOtherSkill hasSkill = userCombVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), skillId);
                    if (null == hasSkill) {
                        UserVehicleOtherSkill vehicleSkill = initVehicleOtherSkill(userCombVehicle, skillId, eVehicleSkillType.Comb.getValue(), 1);
                        userCombVehicle.getOtherSkillList().add(vehicleSkill);
                        if (!syncList.contains(userVehicle)) {
                            syncList.add(userVehicle);
                        }
                    }
                }
            }
        }

        if (VehicleMgr.isUnlockVehicleComb(userVehicle.getTemplateId(), userVehicleMap)) {//解锁组合
            //这里没有因为组合组合技能改变而改变，还是自己的组合的所有都解锁了会解锁第二个技能
            for (int vehicleId : vehicleComb.getVehicleIdList()) {
                UserVehicle userCombVehicle = getUserCombVehicle(vehicleId);
                if (null != userCombVehicle) {
                    // 组合技能
                    int vehicleCombSkillId = vehicleComb.getSkillId(vehicleId);
                    if (vehicleCombSkillId == 0) {
                        continue;
                    }
                    UserVehicleOtherSkill hasSkill = userCombVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), vehicleCombSkillId);
                    if (null == hasSkill) {
                        UserVehicleOtherSkill vehicleSkill = initVehicleOtherSkill(userCombVehicle, vehicleCombSkillId, eVehicleSkillType.Comb.getValue(), 1);
                        userCombVehicle.getOtherSkillList().add(vehicleSkill);
                        if (!syncList.contains(userVehicle)) {
                            syncList.add(userVehicle);
                        }
                    }
                }
            }
        } else {
            for (int vehicleId : vehicleComb.getVehicleIdList()) {
                UserVehicle userCombVehicle = getUserCombVehicle(vehicleId);
                if (null != userCombVehicle) {
                    if (!syncList.contains(userCombVehicle)) {
                        syncList.add(userCombVehicle);
                    }
                }
            }
        }

        // 检测下是否解锁进阶技能
        for (Map.Entry<Integer, Map<Integer, CombSkillUnlockInfo>> entry : vehicleComb.getAdvancedSkillMap().entrySet()) {
            if (entry.getKey() == userVehicle.getTemplateId()) {
                for (Map.Entry<Integer, CombSkillUnlockInfo> unlockInfoEntry : entry.getValue().entrySet()) {
                    int skillId = unlockInfoEntry.getKey();
                    UserVehicleOtherSkill hasSkill = userVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), skillId);
                    if (hasSkill == null) {
                        CombSkillUnlockInfo unlockInfo = unlockInfoEntry.getValue();
                        UserVehicleOtherSkill limitOtherSkill = userVehicle.getVehicleOtherSkill(eVehicleSkillType.Comb.getValue(), unlockInfo.getLimitSkillId());
                        if (limitOtherSkill != null && limitOtherSkill.getSkillLv() >= unlockInfo.getLimitSkillLevel()) {
                            UserVehicleOtherSkill newVehicleSkill = initVehicleOtherSkill(userVehicle, skillId, eVehicleSkillType.Comb.getValue(), 1);
                            userVehicle.getOtherSkillList().add(newVehicleSkill);
                            if (!syncList.contains(userVehicle)) {
                                syncList.add(userVehicle);
                            }
                        }
                    }
                }
            }
        }

        if (syncList.size() > 0) {
            onVehicleListChange(syncList);
            if (isSendMsg) {
                syncVehicleData(syncList, false);
            }
        }
    }


    /**
     * 技能升级
     */
    public int skillUpgrade(String vehicleUid, int skillId, int type) {
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if (null == userVehicle) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        UserVehicleOtherSkill userVehicleOtherSkill = userVehicle.getVehicleOtherSkill(type, skillId);
        if (null == userVehicleOtherSkill) {
            return GameErrorCode.E_VEHICLE_SKILL_NO_FOUND;
        }
        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
        if (null == vehicleInfo) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        VehicleComb vehicleComb = VehicleMgr.getVehicleComb(vehicleInfo.getCombId());
        if (null == vehicleComb) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        SkillInfo skillInfo = SkillMgr.getSkillInfo(skillId);
        if (eVehicleSkillType.Comb.getValue() == type) {//如果是组合技能，判断组合是否激活解锁
            if (!VehicleMgr.isUnlockVehicleComb(userVehicle.getTemplateId(), userVehicleMap) && !vehicleComb.getVehicleSelfSkillMap().containsKey(userVehicle.getTemplateId())) {
                return GameErrorCode.E_VEHICLE_COMB_IS_LOCK;
            }
        }
        int upgradeType = skillInfo.getUpgradeType(0);
        int skillLv = userVehicleOtherSkill.getSkillLv();

        if (null == SkillMgr.getSkillUpgradeInfo(upgradeType, skillLv + 1)) {
            return GameErrorCode.E_VEHICLE_SKILL_LEVEL_MAX;
        }
        SkillUpgradeInfo skillUpgradeInfo = SkillMgr.getSkillUpgradeInfo(upgradeType, skillLv);
        // 判断等级是否够
        if (0 == skillInfo.getMaxLevel()) {//无限制

        } else if (0 < skillInfo.getMaxLevel()) {
            if (skillLv >= skillInfo.getMaxLevel()) {
                return GameErrorCode.E_VEHICLE_SKILL_LEVEL_MAX;
            }
        } else {
            return GameErrorCode.E_VEHICLE_SKILL_TYPE_ERROR;
        }
        //消耗升级道具
        Property consume = new Property(skillInfo.getConsumeGoodsId().get(0), BigInteger.valueOf(skillUpgradeInfo.getConsumeCount()));
        if (!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Vehicle, eLogMoneyType.VehicleSkillUpgrade)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        int oldLv = userVehicleOtherSkill.getSkillLv();
        userVehicleOtherSkill.setSkillLv(userVehicleOtherSkill.getSkillLv() + 1);
        checkVehicleCombUnlock(userVehicle, vehicleInfo, true);
        onVehicleChange(userVehicle);
        return 0;
    }

    public Map<String, UserVehicle> getUserVehicleMap() {
        return userVehicleMap;
    }

    public int getVehicleCount() {
        int count = 0;
        if (null != userVehicleMap) {
            for (UserVehicle userVehicle : userVehicleMap.values()) {
                if (VehicleMgr.isUserVehicleExist(userVehicle)) {
                    count++;
                }
            }
        }
        return count;
    }

    public int getEquipVehicleCount() {
        int count = 0;
        if (null != userVehicleMap) {
            for (UserVehicle userVehicle : userVehicleMap.values()) {
                if (VehicleMgr.isUserVehicleExist(userVehicle) && userVehicle.getPatronsId() > 0) {
                    count++;
                }
            }
        }
        return count;
    }

    /**
     * 每天重置
     */
    public void resetOneDay() {
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp() / 1000;
        List<UserVehicle> syncList = new ArrayList<>();
        if (null != userVehicleMap) {
            for (UserVehicle userVehicle : userVehicleMap.values()) {
                if (userVehicle.getLastUpdateTime() < zeroTime) {
                    // 不等于0才同步
                    if (userVehicle.getEquipTimes() != 0 || userVehicle.getEquipBuyTimes() != 0) {
                        syncList.add(userVehicle);
                    }
                    userVehicle.setEquipTimes(0);
                    userVehicle.setEquipBuyTimes(0);
                    userVehicle.setLastUpdateTime(zeroTime);
                }
            }
        }
        if (syncList.size() > 0) {
            syncVehicleData(syncList, false);
        }
    }

    public void checkSoulBlock() {
        if(!SystemOpenMgr.systemOpen(player, eSystemId.VehicleSoul.getValue())){
            return;
        }
        if (null != userVehicleMap) {
            for(UserVehicle userVehicle : userVehicleMap.values()){
                VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
                if(vehicleInfo.getQuality() >= 6){
                    List<Integer> initSoulBlockList = StringUtils.stringToIntegerList(GameConfig.VEHICLES_SOUL_BEGIN_NUM,"\\|");
                    if(userVehicle.getSoulBlockList().size() == 0){
                        userVehicle.setSoulBlockList(initSoulBlockList);
                    }
                }else{
                    //去掉一开始都有空，没判断无双才有
                    if(userVehicle.getSoulBlockList().size() > 0){
                        userVehicle.setSoulBlockList(new ArrayList<>());
                    }
                }

            }
        }
    }

    public void openSoulBlock(String vehicleId) {
        if(!SystemOpenMgr.systemOpen(player, eSystemId.VehicleSoul.getValue())){
            return;
        }
        if (null != userVehicleMap && userVehicleMap.containsKey(vehicleId)) {
            UserVehicle userVehicle = userVehicleMap.get(vehicleId);
            VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
            if(vehicleInfo.getQuality() >= 6){
                List<Integer> initSoulBlockList = StringUtils.stringToIntegerList(GameConfig.VEHICLES_SOUL_BEGIN_NUM,"\\|");
                if(userVehicle.getSoulBlockList().size() == 0){
                    userVehicle.setSoulBlockList(initSoulBlockList);
                }
            }
        }
    }

    public void checkAndReset() {
        int hours = DateHelper.getHours();
        long now = System.currentTimeMillis() / 1000;
        long needResetTime = DateHelper.getDateByHours(22).getTime() / 1000;
        boolean needSync = false;
        for (PatronsVehicleBindingData data : new ArrayList<>(patronsVehicleBindingDataMap.values())) {
            long lastResetTime = data.getLastUpdateTime() / 1000;
            if (DateHelper.isSameDay(now, lastResetTime)) {
                //如果是同一天 只有过了22点才行
                //有绑定的活动，都是22点不能玩，所以重置？没备注，我猜的
                if (hours < 22) {
                    continue;
                }
                if (lastResetTime >= needResetTime) {
                    continue;
                }
            }
            if (now < data.getSystemEndTime()) {
                continue;
            }
            data.setLastUpdateTime(now * 1000);
            data.setPatronsId(0);
            data.getActivityIdList().clear();
            needSync = true;
        }
        if (needSync) {
            syncPatronsBindMsg(new ArrayList<>(patronsVehicleBindingDataMap.values()));
        }
    }

    public void checkVehicleBindingActivity() {
        List<PatronsVehicleBindingData> syncList = new ArrayList<>();
        for (PatronsVehicleBindingData data : new ArrayList<>(patronsVehicleBindingDataMap.values())) {
            boolean needSync = false;
            List<Integer> activityIdList = new ArrayList<>(data.getActivityIdList());
            for (Integer activityId : activityIdList) {
                ActivityInfo activityInfo = NormalActivityMgr.getActivityInfo(activityId);
                if (activityInfo == null) {
                    activityInfo = StrongholdActivityMgr.getInTimeActivityInfo(activityId);
                }
                if (activityInfo == null) {
                    data.removeActivityId(activityId);
                    needSync = true;
                }
            }
            if (needSync) {
                syncList.add(data);
            }
        }
        if (syncList.size() > 0) {
            syncPatronsBindMsg(syncList);
        }
    }

    private void syncVehicleDetail() {
        player.sendPacket(Protocol.U_VEHICLE_DATA_SYNC, VehiclePb.parseVehicleDetailMsg(userVehicleDetail));
    }

    public void syncVehicleData(List<UserVehicle> vehicleList, boolean isLogin) {
        if (isLogin) {
            if (vehicleList.size() > VehicleMgr.ONCE_SEND_VEHICLE_COUNT) {//珍兽数量太多，分次下发
                do {
                    int count = vehicleList.size();
                    if (count > VehicleMgr.ONCE_SEND_VEHICLE_COUNT) {
                        count = VehicleMgr.ONCE_SEND_VEHICLE_COUNT;
                    }
                    List<UserVehicle> tempList = new ArrayList<>(vehicleList.subList(0, count));
                    player.sendPacket(Protocol.U_VEHICLE_LIST, VehiclePb.parseVehicleListMsg(tempList));
                    vehicleList.removeAll(tempList);
                } while (vehicleList.size() > 0);
            } else {
                player.sendPacket(Protocol.U_VEHICLE_LIST, VehiclePb.parseVehicleListMsg(vehicleList));
            }
        } else {
            player.sendPacket(Protocol.U_VEHICLE_SYNC, VehiclePb.parseVehicleListMsg(vehicleList));
        }
    }

    public void syncVehicleData(UserVehicle userVehicle) {
        if (null == userVehicle) {
            return;
        }
        List<UserVehicle> syncList = new ArrayList<>();
        syncList.add(userVehicle);
        syncVehicleData(syncList, false);
    }

    /**
     * 增加座骑
     */
    public int addVehicle(int templateId, int num, eLogMoneyType master, eLogMoneyType son) {
        if (num <= 0) {
            return GameErrorCode.E_MALL_COUNT_NOT_ZERO;
        }

        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(templateId);
        //组合珍兽只能获得一次，直接返回
        if (vehicleInfo.getCombId() > 0 && getUserCombVehicle(templateId) != null) {
            return 0;
        }
        int oldCount = userVehicleDetail.getTemplateIdList().size();
        boolean enableAutoRecycle = userVehicleDetail.isEnableAutoRecycle();
        List<Integer> autoRecycleList = userVehicleDetail.getAutoRecycleList();

        for (int i = 0; i < num; i++) {
            UserVehicle userVehicle = initUserVehicle(vehicleInfo);
            // 随机技能
            initSkill(userVehicle, vehicleInfo);
            if (0 == userVehicleDetail.getTotalCount()) {//第一只珍兽，特殊处理一下
                firstVehicleProcess(userVehicle);
            }
            userVehicleMap.put(userVehicle.getVehicleUid(), userVehicle);
            checkVehicleCombUnlock(userVehicle, vehicleInfo, true);
            userVehicleDetail.addTemplateId(templateId);
            userVehicleDetail.setTotalCount(userVehicleDetail.getTotalCount() + 1);
            if (vehicleInfo.getQuality() >= 6) {
                userVehicleDetail.setQualitySixAboveTotalCount(userVehicleDetail.getQualitySixAboveTotalCount() + 1);
            }
            openSoulBlock(userVehicle.getVehicleUid());
            syncVehicleData(userVehicle);
            vehicleRankChange(userVehicle);
            // 珍兽获得日志
            AutoLogMgr.add(new LogGetVehicle(player.getUserId(), userVehicle.getVehicleUid(), userVehicle.getTemplateId(), master.getValue(), son.getValue()));
            DataAnalyticsMgr.trackVehicleGetPet(player, userVehicle);

            if (enableAutoRecycle && autoRecycleList.contains(templateId)) {
                addRecycleVehicleUID(userVehicle.getVehicleUid());
            }
        }
        if (userVehicleDetail.getTemplateIdList().size() > oldCount) {
            syncVehicleDetail();
            player.notifyListener(eGamePlayerEventType.VehicleTotalType.getValue(), userVehicleDetail);
        }
        //成就、任务
        player.notifyListener(eGamePlayerEventType.VehicleTotalCount.getValue(), userVehicleDetail);
        player.notifyListener(eGamePlayerEventType.VehicleQualitySixAboveTotalCount.getValue(), userVehicleDetail);
        player.notifyListener(eGamePlayerEventType.HasQualificationVehicleCount.getValue(), new VehicleArgs(userVehicleMap));
        player.notifyListener(eGamePlayerEventType.VehicleTotalLevel.getValue(), new VehicleArgs(userVehicleMap));

        return 0;
    }

    public UserVehicle addRobotVehicle(int templateId) {
        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(templateId);
        //组合珍兽只能获得一次，直接返回
        if (vehicleInfo.getCombId() > 0 && getUserCombVehicle(templateId) != null) {
            return null;
        }
        UserVehicle userVehicle = initUserVehicle(vehicleInfo);
        // 随机技能
        initSkill(userVehicle, vehicleInfo);
        userVehicleMap.put(userVehicle.getVehicleUid(), userVehicle);
        checkVehicleCombUnlock(userVehicle, vehicleInfo, false);
        userVehicleDetail.addTemplateId(templateId);
        userVehicleDetail.setTotalCount(userVehicleDetail.getTotalCount() + 1);
        if (vehicleInfo.getQuality() >= 6) {
            userVehicleDetail.setQualitySixAboveTotalCount(userVehicleDetail.getQualitySixAboveTotalCount() + 1);
        }
        vehicleRankChange(userVehicle);
        return userVehicle;
    }

    private void firstVehicleProcess(UserVehicle userVehicle) {
        UserVehicleSkill firstSkill = userVehicle.getSkillMapEffect().get(1);
        UserVehicleSkill secondSkill = userVehicle.getSkillMapEffect().get(2);
        if (null != firstSkill) {
            firstSkill.setSkillType(eOccupationType.Farmer.getValue());
            firstSkill.setValue(12);
        }
        if (null != secondSkill) {
            secondSkill.setSkillType(eOccupationType.Scholar.getValue());
            secondSkill.setValue(5);
        }
    }

    /**
     * 初始化座骑技能
     */
    private void initSkill(UserVehicle userVehicle, VehicleInfo vehicleInfo) {
        if (userVehicle == null || vehicleInfo == null) {
            log.error("userVehicle or vehicleInfo is null !!!");
            return;
        }
        int maxPos = vehicleInfo.getDefaultSkillCount() + userVehicle.getStudyLv();
        for (int i = 0; i < maxPos; i++) {
            if (!userVehicle.getSkillMap().containsKey(i + 1)) {
                VehicleSkillInfo randomSkill = VehicleMgr.getRandomSkill(false, 0);
                UserVehicleSkill userVehicleSkill = initUserVehicleSkill(userVehicle.getVehicleUid(), i + 1, randomSkill);
                userVehicle.getSkillMap().put(userVehicleSkill.getSkillPos(), userVehicleSkill);
            }
        }
        for (Map.Entry<Integer, UserVehicleSkill> entry : userVehicle.getSkillMap().entrySet()) {
            UserVehicleSkill userVehicleSkill = entry.getValue();
            if (userVehicleSkill.getSkillPos() > maxPos) {
                userVehicleSkill.setValue(0);
                userVehicleSkill.setSkillModifyTimes(0);
                userVehicleSkill.setRandomSkillType(0);
                userVehicleSkill.setRandomValue(0);
                userVehicleSkill.setInvalid(true);
            }
        }
    }

    //初始化座驾的其他技能，光环等,有就初始化，没有就不管
    public UserVehicleOtherSkill initVehicleOtherSkill(UserVehicle userVehicle, int skillId, int type, int skillLv) {
        UserVehicleOtherSkill skill = new UserVehicleOtherSkill();
        skill.setUserId(userVehicle.getUserId());
        skill.setVehicleUid(userVehicle.getVehicleUid());
        skill.setSkillId(skillId);
        skill.setSkillLv(skillLv);
        skill.setSkillType(type);
        skill.setInsertOption();
        return skill;
    }

    /**
     * 座骑升级
     */
    public int vehicleUpgrade(String vehicleUid, int times) {
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        VehicleBreak vehicleBreak = VehicleMgr.getVehicleBreak(userVehicle.getBreakLv());
        int maxLevel = VehicleMgr.getVehicleMaxLevel(player, vehicleBreak.getCurrentMaxLv());
        if (userVehicle.getLevel() + times > maxLevel) {//已经满级
            return GameErrorCode.E_VEHICLE_LEVEL_MAX;
        }
        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());

        //获取升级消耗
        Property consume = VehicleMgr.getVehicleUpgradeConsume(vehicleInfo);
        if(times > 1){
            consume.rideProperty(times);
        }
        if (!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Vehicle, eLogMoneyType.VehicleUpgrade)) {//升级道具不足
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        //增加等级
        int oldLv = userVehicle.getLevel();
        userVehicle.setLevel(userVehicle.getLevel() + times);
        userVehicleDetail.setTotalUpgradeTimes(userVehicleDetail.getTotalUpgradeTimes() + times);

        DataAnalyticsMgr.trackVehiclePetLevelUp(player, userVehicle);

        onVehicleChange(userVehicle);
        //成就、任务
        player.notifyListener(eGamePlayerEventType.HasQualificationVehicleCount.getValue(), new VehicleArgs(userVehicleMap));
        player.notifyListener(eGamePlayerEventType.ExistVehicleTotalUpgradeTimes.getValue(), new VehicleArgs(userVehicleMap));
        player.notifyListener(eGamePlayerEventType.VehicleTotalUpgradeTimes.getValue(), userVehicleDetail);
        player.notifyListener(eGamePlayerEventType.VehicleTotalLevel.getValue(), new VehicleArgs(userVehicleMap));
        player.notifyListener(eGamePlayerEventType.VehicleUpgradeTimes.getValue(), times);
        player.notifyListener(eGamePlayerEventType.UnionVehicleUpgradeTimes.getValue(), new UnionActivityTaskArgs(UnionActivityTaskArgs.TYPE_ADD_VALUE, times, player.getUserInfo().getUnionUid()));
        // 现金礼包
        player.notifyListener(eGamePlayerEventType.RechargeNewPlayerVehiclePackage.getValue(), 0);

        // 珍兽升级日志
        AutoLogMgr.add(new LogVehicleUpgrade(player.getUserId(), userVehicle.getVehicleUid(), userVehicle.getTemplateId(), oldLv, userVehicle.getLevel(), PropertyHelper.parsePropertyToString(consume)));
        return 0;
    }

    /**
     * 座骑突破
     */
    public int vehicleBreak(String vehicleUid) {
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
        if (!vehicleInfo.isCanBreak()) {
            return GameErrorCode.E_VEHICLE_CAN_NO_BREAK;
        }
        VehicleBreak vehicleBreak = VehicleMgr.getVehicleBreak(userVehicle.getBreakLv());
        if (userVehicle.getLevel() < vehicleBreak.getCurrentMaxLv()) {//等级不足
            return GameErrorCode.E_VEHICLE_LEVEL_NO_ENOUGH;
        }
        VehicleBreak nextVehicleBreak = VehicleMgr.getVehicleBreak(userVehicle.getBreakLv() + 1);
        if (null == nextVehicleBreak) {
            return GameErrorCode.E_VEHICLE_BREAK_LEVEL_MAX;
        }

        //突破消耗
        if (!player.getModule(CurrencyModule.class).removeCurrency(vehicleBreak.getConsume(), eLogMoneyType.Vehicle, eLogMoneyType.VehicleBreak)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        //增加突破
        userVehicle.setBreakLv(userVehicle.getBreakLv() + 1);

        return 0;
    }

    /**
     * 座骑研习
     */
    public int vehicleStudy(int type, String vehicleUid) {
        if (0 == type) {
            return GameErrorCode.E_VEHICLE_STUDY_TYPE_ERROR;
        }
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
        if (!vehicleInfo.hasStudyType(type)) {
            return GameErrorCode.E_VEHICLE_CAN_NO_STUDY;
        }
        int maxStudyTimes = VehicleMgr.getVehicleMaxStudyTimes(player);
        if (userVehicle.getStudyLv() >= maxStudyTimes) {
            return GameErrorCode.E_VEHICLE_STUDY_LEVEL_MAX;
        }
        VehicleStudy nextVehicleStudy = VehicleMgr.getVehicleStudy(type, userVehicle.getStudyLv() + 1);
        if (null == nextVehicleStudy) {
            return GameErrorCode.E_VEHICLE_STUDY_LEVEL_MAX;
        }

        //消耗
        VehicleStudy vehicleStudy = VehicleMgr.getVehicleStudy(type, userVehicle.getStudyLv());
        if (!player.getModule(CurrencyModule.class).removeCurrency(vehicleStudy.getConsume(), eLogMoneyType.Vehicle, eLogMoneyType.VehicleStudy)) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        //加研习等级
        int oldLv = userVehicle.getStudyLv();
        userVehicle.setStudyLv(userVehicle.getStudyLv() + 1);
        int skillPos = vehicleInfo.getDefaultSkillCount() + userVehicle.getStudyLv();
        //增加技能格子并随机技能
        VehicleSkillInfo randomSkill = VehicleMgr.getRandomSkill(false, 0);
        UserVehicleSkill userVehicleSkill = initUserVehicleSkill(vehicleUid, skillPos, randomSkill);
        userVehicle.getSkillMap().put(userVehicleSkill.getSkillPos(), userVehicleSkill);
        onVehicleChange(userVehicle);
        //成就、任务
        player.notifyListener(eGamePlayerEventType.VehicleSkillValidCount.getValue(), new VehicleArgs(userVehicleMap));
        WorldMessageMgr.worldNotify(eMessageType.VehicleStudy.getValue(), player.getUserInfo().getCity(), player.getTitleId(),
                player.getUserInfo().getNickName(), userVehicle.getTemplateId(), userVehicle.getStudyLv());

        // 加个日志
        AutoLogMgr.add(new LogVehicleStudy(
                player.getUserId(),
                userVehicle.getVehicleUid(),
                userVehicle.getTemplateId(),
                type,
                oldLv,
                userVehicle.getStudyLv(),
                PropertyHelper.parsePropertyToString(vehicleStudy.getConsume()))
        );
        return 0;
    }

    /**
     * 座骑改装技能
     *
     * @param vehicleUid  座骑唯一标识
     * @param skillPos    技能位置
     * @param isCustomize 是否定制
     * @return 改装结果
     */
    public VehicleModifySkillResult randomSkill(String vehicleUid, int skillPos, boolean isCustomize, boolean isAuto) {
        VehicleModifySkillResult result = new VehicleModifySkillResult();
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            result.setRet(GameErrorCode.E_VEHICLE_NO_FOUND);
            return result;
        }
        UserVehicleSkill vehicleSkill = userVehicle.getSkillMapEffect().get(skillPos);
        if (null == vehicleSkill) {
            result.setRet(GameErrorCode.E_VEHICLE_SKILL_NO_FOUND);
            return result;
        }

        int occupation = 0;
        Property consume;
        if (isCustomize) {//定制改装
            consume = new Property(GameConfig.VEHICLE_SKILL_CUSTOM_MODIFY_ITEM, BigInteger.ONE);
            if (!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Vehicle, eLogMoneyType.VehicleCustomModifySkill)) {
                result.setRet(GameErrorCode.E_BAG_ITEM_NO_ENOUGH);
                return result;
            }
            if (isAuto) {
                playerVehicleAutoModifyCost.addItemCost(consume.getCountByGoodsId(GameConfig.VEHICLE_SKILL_CUSTOM_MODIFY_ITEM).longValue());
            }
        } else {
            BigInteger silver = VehicleMgr.getModifySkillCost(vehicleSkill.getSkillModifyTimes());
            consume = new Property(GameConfig.GAME_MONEY_SILVER, silver);
            if (!player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.Vehicle, eLogMoneyType.VehicleModifySkill)) {
                result.setRet(GameErrorCode.E_BAG_SILVER_NO_ENOUGH);
                return result;
            }
            if (isAuto) {
                playerVehicleAutoModifyCost.addSliverCost(consume.getCountByGoodsId(GameConfig.GAME_MONEY_SILVER).longValue());
            }
            if (userVehicle.getPatronsId() > 0 && vehicleSkill.getSkillModifyTimes() < ConfigMgr.getVehicleSkillModifyParam1()) {
                PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(userVehicle.getPatronsId());
                occupation = patronsInfo.getOccupation();
            }
        }
        //获取随机技能
        VehicleSkillInfo randomSkill = VehicleMgr.getRandomSkill(isCustomize, occupation);

        //技能改装次数加1
        if (!isCustomize) {//只记录非定制改装次数
            vehicleSkill.setSkillModifyTimes(vehicleSkill.getSkillModifyTimes() + 1);
        }
        if (0 == userVehicleDetail.getSkillModifyTotalTimes()) {
            firstModifyVehicleSkill(randomSkill);
        }
        userVehicleDetail.setSkillModifyTotalTimes(userVehicleDetail.getSkillModifyTotalTimes() + 1);
        //缓存改装技能
        vehicleSkill.setRandomSkillType(randomSkill.getSkillType());
        vehicleSkill.setRandomValue(randomSkill.getValue());

        result.setRet(0);
        result.setVehicleSkill(vehicleSkill);
        //成就、任务
        player.notifyListener(eGamePlayerEventType.VehicleSkillModifyTimes.getValue(), 1);
        player.notifyListener(eGamePlayerEventType.VehicleTotalSkillModifyTimes.getValue(), userVehicleDetail);

        // 加个日志
        AutoLogMgr.add(new LogVehicleSkillRefine(
                player.getUserId(),
                userVehicle.getVehicleUid(),
                userVehicle.getTemplateId(),
                skillPos,
                randomSkill.getSkillType(),
                randomSkill.getValue(),
                isCustomize,
                PropertyHelper.parsePropertyToString(consume)
        ));
        return result;
    }

    private void firstModifyVehicleSkill(VehicleSkillInfo vehicleSkillInfo) {
        vehicleSkillInfo.setSkillType(eOccupationType.Farmer.getValue());
        vehicleSkillInfo.setValue(ConfigMgr.getVehicleSkillCustomModifyParamList().size());
    }


    public int giveUpRandomSkill(String vehicleUid, int pos) {
        UserVehicle userVehicle = userVehicleMap.get(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        UserVehicleSkill vehicleSkill = userVehicle.getSkillMapEffect().get(pos);
        if (null == vehicleSkill) {
            return GameErrorCode.E_VEHICLE_SKILL_NO_FOUND;
        }
        vehicleSkill.setRandomSkillType(0);
        vehicleSkill.setRandomValue(0);
        VehicleProto.GiveUpRandomSkillRespMsg.Builder respMsg = VehicleProto.GiveUpRandomSkillRespMsg.newBuilder();
        respMsg.setVehicleUid(vehicleUid);
        VehicleProto.VehicleSkillTempMsg.Builder skillMsg = VehiclePb.parseVehicleSkillTempMsg(vehicleSkill);
        if(null != skillMsg) {
            respMsg.setSkill(skillMsg);
        }
        respMsg.setRet(0);
        player.sendPacket(ClientProtocol.U_GIVE_UP_VEHICLE_RANDOM_SKILL, respMsg);
        return 0;
    }
    /**
     * 替换座骑改装技能
     *
     * @param vehicleUid 座骑唯一标识
     * @param skillPos   技能位置
     * @return 替换结果
     */
    public VehicleModifySkillResult agreeModifySkill(String vehicleUid, int skillPos) {
        VehicleModifySkillResult result = new VehicleModifySkillResult();
        UserVehicle userVehicle = userVehicleMap.get(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            result.setRet(GameErrorCode.E_VEHICLE_NO_FOUND);
            return result;
        }
        UserVehicleSkill vehicleSkill = userVehicle.getSkillMapEffect().get(skillPos);
        if (null == vehicleSkill) {
            result.setRet(GameErrorCode.E_VEHICLE_SKILL_NO_FOUND);
            return result;
        }
        //在缓存中找到改装的技能信息
        if (0 == vehicleSkill.getRandomSkillType()) {
            result.setRet(GameErrorCode.E_VEHICLE_SKILL_MODIFY_FAIL);
            return result;
        }

        //替换技能信息
        int oldType = vehicleSkill.getSkillType();
        int oldValue = vehicleSkill.getValue();
        vehicleSkill.setSkillType(vehicleSkill.getRandomSkillType());
        vehicleSkill.setValue(vehicleSkill.getRandomValue());
        vehicleSkill.setRandomSkillType(0);
        vehicleSkill.setRandomValue(0);
        onVehicleChange(userVehicle);
        result.setRet(0);
        result.setVehicleSkill(vehicleSkill);
        //成就、任务
        player.notifyListener(eGamePlayerEventType.VehicleSkillValidCount.getValue(), new VehicleArgs(userVehicleMap));

        // 加个日志
        AutoLogMgr.add(new LogVehicleSkillModify(
                player.getUserId(),
                userVehicle.getVehicleUid(),
                userVehicle.getTemplateId(),
                skillPos,
                oldType,
                oldValue,
                vehicleSkill.getSkillType(),
                vehicleSkill.getValue()
        ));
        return result;
    }

    /**
     * 座骑回收
     *
     * @param vehicleUidList 回收座骑唯一标识列表
     * @return 回收结果
     */
    public VehicleRecycleResult vehicleRecycle(List<String> vehicleUidList, boolean autoRecycle) {
        VehicleRecycleResult result = new VehicleRecycleResult();
        if (null == vehicleUidList) {
            result.setRet(GameErrorCode.E_VEHICLE_NO_VEHICLE_RECYCLE);
            return result;
        }

        if (isRecycleLock()) {
            result.setRet(GameErrorCode.E_VEHICLE_RECYCLE_LOCK);
            return result;
        }

        Property totalConsume = new Property();
        Property recycleVehicleCnt = new Property(); // 回收珍兽统计
        int recycleCount = 0;
        List<String> recycleVehicleUidList = new ArrayList<>();
        List<UserVehicle> deleteRankVehicleList = new ArrayList<>();
        for (String vehicleUid : vehicleUidList) {
            UserVehicle userVehicle = getUserVehicle(vehicleUid);
            if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
                continue;
            }
            if (userVehicle.getPatronsId() > 0) {//装备中不能回收
                continue;
            }
            VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
            if (!vehicleInfo.isCanRecycle()) {//不可回收
                continue;
            }

            Property consume = new Property();
            //计算升级材料
            consume.addProperty(VehicleMgr.getVehicleTotalUpgradeConsume(userVehicle));
            //计算突破材料
            VehicleBreak vehicleBreak = VehicleMgr.getVehicleBreak(userVehicle.getBreakLv());
            consume.addProperty(vehicleBreak.getTotalConsume());
            //计算学习材料
            int type = vehicleInfo.getRecycleStudyType();
            if (type > 0) {
                VehicleStudy vehicleStudy = VehicleMgr.getVehicleStudy(type, userVehicle.getStudyLv());
                consume.addProperty(vehicleStudy.getTotalConsume());
            }
            //计算回收材料
            consume.addProperty(vehicleInfo.getRecycleReward());

            totalConsume.addProperty(consume);

            //魂孔开了多少返还
            totalConsume.addProperty(VehicleSoulMgr.getSoulBlockConsume(userVehicle.getSoulBlockList().size()));
            player.getModule(VehicleSoulModule.class).unloadSoul(vehicleUid);

            //炼魂等级回收
            Property boneLvConsume = SkillMgr.calcSkillLvTotalConsume(vehicleInfo.getBonePowerSkill(), 0, userVehicle.getBoneLv(), 0);
            totalConsume.addProperty(boneLvConsume);

            //魂骨卸下来
            player.getModule(VehicleBoneModule.class).vehicleUnEquipAllBone(vehicleUid);

            //删除座骑
            userVehicle.setDelete(true);
            recycleCount++;
            recycleVehicleUidList.add(vehicleUid);
            if (VehicleMgr.canJoinRank(userVehicle.getTemplateId()) && isBestVehicleInType(userVehicle)) {
                deleteRankVehicleList.add(userVehicle);
            }

            // 珍兽回收日志
            AutoLogMgr.add(new LogDeleteVehicle(player.getUserId(), userVehicle.getVehicleUid(), userVehicle.getTemplateId(),
                    userVehicle.getLevel(), userVehicle.getBreakLv(), userVehicle.getStudyLv(), userVehicle.getCreateTime(),
                    PropertyHelper.parsePropertyToString(consume), autoRecycle));
            DataAnalyticsMgr.trackVehicleBackPet(player, userVehicle);

            recycleVehicleCnt.addProperty(userVehicle.getTemplateId(), 1);
        }
        if (recycleCount <= 0) {
            result.setRet(GameErrorCode.E_VEHICLE_NO_VEHICLE_RECYCLE);
            return result;
        }
        userVehicleDetail.setTotalDeleteCount(userVehicleDetail.getTotalDeleteCount() + recycleCount);

        //增加回收材料
        player.getModule(CurrencyModule.class).addCurrency(totalConsume, eLogMoneyType.Vehicle, eLogMoneyType.VehicleRecycle);

        //成就、任务
        player.notifyListener(eGamePlayerEventType.VehicleTotalDeleteCount.getValue(), userVehicleDetail);
        //榜单变化
        if (deleteRankVehicleList.size() > 0) {
            Map<Integer, UserVehicle> bestRankVehicleMap = getBestRankVehicleMap();
            for (UserVehicle deleteVehicle : deleteRankVehicleList) {
                if (bestRankVehicleMap.containsKey(deleteVehicle.getTemplateId())) {
                    // 有同类型的其他珍兽：替换排行
                    vehicleRankChange(bestRankVehicleMap.get(deleteVehicle.getTemplateId()));
                } else {
                    // 删除排行
                    vehicleRankChange(deleteVehicle, true);
                }
            }
        }
        result.setRet(0);
        result.setRecycleVehicleUidList(recycleVehicleUidList);
        result.setRecycleReward(PropertyHelper.parsePropertyToString(totalConsume));
        result.setRecycleVehicleStr(PropertyHelper.parsePropertyToString(recycleVehicleCnt));
        return result;
    }

    /**
     * 重置珍兽
     * @param vehicleUid 珍兽
     * @return
     */
    public int vehicleReset(String vehicleUid){
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            return GameErrorCode.E_VEHICLE_NO_FOUND;
        }
        if (userVehicle.getPatronsId() > 0) {//装备中
            return GameErrorCode.E_VEHICLE_HAS_EQUIP;
        }
        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(userVehicle.getTemplateId());
        if (vehicleInfo.isCanRecycle()) {  //可回收的不可重置
            return GameErrorCode.E_VEHICLE_CAN_NOT_RESET;
        }

//        if (userVehicle.getResetTimes() >= GameConfig.VEHICLES_RESET_NUM) {
//            return GameErrorCode.E_VEHICLE_RESET_MAX_TIMES;
//        }
        //6.7.0优化 cd内不给重置 但是可以多次重置了
        if (userVehicleDetail.getLastResetTime() + (DateHelper.HOUR_MILLIONS * GameConfig.VEHICLES_RESET_CD) > System.currentTimeMillis()){
            return GameErrorCode.E_VEHICLE_RESET_IN_CD;
        }
        //6.7.0优化 如果没开孔的不给重置 没升级的不给重置
        if (userVehicle.getSoulBlockList().size() <= 9 && userVehicle.getLevel() <= 1 && userVehicle.getStudyLv()<=0){
            return GameErrorCode.E_VEHICLE_RESET_CONDITION_NO_COMPLETE;
        }

        userVehicleDetail.setLastResetTime(System.currentTimeMillis());

        Property consume = new Property();
        UserVehicle cloneVehicle = new UserVehicle();
        //计算升级材料
        cloneVehicle.setStudyLv(userVehicle.getStudyLv());
        cloneVehicle.setTemplateId(userVehicle.getTemplateId());
        cloneVehicle.setLevel(userVehicle.getLevel());
        consume.addProperty(VehicleMgr.getVehicleTotalUpgradeConsume(cloneVehicle));
        //计算学习材料
        int type = vehicleInfo.getRecycleStudyType();
        //104504青龙id，按龙角返还
        if(vehicleInfo.getId() == 104504 && vehicleInfo.getStudyTypeList().size() > 1) {
            type = vehicleInfo.getStudyTypeList().get(1);
        }
        if (type > 0) {
            VehicleStudy vehicleStudy = VehicleMgr.getVehicleStudy(type, userVehicle.getStudyLv());
            consume.addProperty(vehicleStudy.getTotalConsume());
        }
        //计算回收材料 不是回收 不需要返还回收材料吧
       // consume.addProperty(vehicleInfo.getRecycleReward());

        //只有无双可以重置
        //优化,兽魂独立重置
//        player.getModule(VehicleSoulModule.class).unloadSoul(vehicleUid);
//        consume.addProperty(VehicleSoulMgr.getSoulBlockConsume(userVehicle.getSoulBlockList().size()));
//        List<Integer> initSoulBlockList = StringUtils.stringToIntegerList(GameConfig.VEHICLES_SOUL_BEGIN_NUM,"\\|");
//        userVehicle.setSoulBlockList(initSoulBlockList);

        //重置后的初始技能位置
        for (Map.Entry<Integer, UserVehicleSkill> skillEntry : userVehicle.getSkillMap().entrySet()) {
            UserVehicleSkill skill = skillEntry.getValue();
            if(skill.getSkillPos() > vehicleInfo.getDefaultSkillCount()){
                skill.setInvalid(true);
            }
        }
        userVehicle.setStudyLv(0);
        userVehicle.setLevel(1);
        userVehicle.setResetTimes(1 + userVehicle.getResetTimes());

        //炼魂等级回收
        if (userVehicle.getBoneLv() > 0) {
            Property boneLvConsume = SkillMgr.calcSkillLvTotalConsume(vehicleInfo.getBonePowerSkill(), 0, userVehicle.getBoneLv(), 0);
            consume.addProperty(boneLvConsume);
            userVehicle.setBoneLv(1);
            userVehicle.setBoneHole(1);
        }

        //魂骨卸下来
        player.getModule(VehicleBoneModule.class).vehicleUnEquipAllBone(vehicleUid);

        //增加重置返回材料
        player.getModule(CurrencyModule.class).addCurrency(consume, eLogMoneyType.Vehicle, eLogMoneyType.VehicleReset);

        VehicleProto.VehicleResetRespMsg.Builder respMsg = VehicleProto.VehicleResetRespMsg.newBuilder();
        respMsg.setRewards(PropertyHelper.parsePropertyToString(consume));
        respMsg.setRet(0);
        respMsg.setVehicle(VehiclePb.parseVehicleTempMsg(userVehicle));
        player.sendPacket(Protocol.U_VEHICLE_RESET, respMsg);

        syncVehicleData(userVehicle);
        syncLastResetVehicleTime();

        // 珍兽重置日志
        AutoLogMgr.add(new LogVehicleReset(player.getUserId(),
                userVehicle.getVehicleUid(),
                userVehicle.getTemplateId(),
                userVehicle.getLevel(),
                userVehicle.getBreakLv(),
                userVehicle.getStudyLv(),
                userVehicle.getCreateTime(),
                PropertyHelper.parsePropertyToString(consume))
        );
        return 0;
    }

    /**
     * 同步上一次重置的时间
     */
    public void syncLastResetVehicleTime(){
        if (userVehicleDetail == null){
            return;
        }
        VehicleProto.VehicleResetTimeResetSyncMsg.Builder builder = VehicleProto.VehicleResetTimeResetSyncMsg.newBuilder().setLastResetTime(userVehicleDetail.getLastResetTime());
        player.sendPacket(ClientProtocol.U_VEHICLE_LAST_RESET_TIME_SYNC,builder);
    }

    /**
     * 卸下门客座骑
     */
    public void dismountVehicle(UserVehicle userVehicle) {
        int patronsId = userVehicle.getPatronsId();
        userVehicle.setPatronsId(0);
        syncVehicleData(userVehicle);
        vehicleRankChange(userVehicle);
        //成就、任务
        player.notifyListener(eGamePlayerEventType.VehicleEquipCount.getValue(), new VehicleArgs(userVehicleMap));
        player.notifyListener(eGamePlayerEventType.VehicleSkillValidCount.getValue(), new VehicleArgs(userVehicleMap));
        //商会战活动
        UnionPhaseWarMgr.dismountVehicle(player, patronsId, userVehicle.getVehicleUid());
        // 日志
        AutoLogMgr.add(new LogVehicleEquip(
                player.getUserId(),
                userVehicle.getVehicleUid(),
                userVehicle.getTemplateId(),
                patronsId,
                0
        ));
    }

    /**
     * 门客装备座骑
     */
    public void equipVehicle(String vehicleUid, int patronsId) {
        //如果门客有装备座骑，先把门客装备的座骑卸下
        UserVehicle patronsVehicle = getUserVehicleByPatrons(patronsId);
        if (null != patronsVehicle) {
            patronsVehicle.setPatronsId(0);
            syncVehicleData(patronsVehicle);
        }
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        userVehicle.setPatronsId(patronsId);
        userVehicle.setEquipTimes(userVehicle.getEquipTimes() + 1);
        syncVehicleData(userVehicle);
        //榜单
        vehicleRankChange(userVehicle);
        //成就、任务
        player.notifyListener(eGamePlayerEventType.VehicleEquipCount.getValue(), new VehicleArgs(userVehicleMap));
        player.notifyListener(eGamePlayerEventType.VehicleSkillValidCount.getValue(), new VehicleArgs(userVehicleMap));
        //商会战活动
        UnionPhaseWarMgr.equipVehicle(player, vehicleUid, patronsId);

        // 日志
        AutoLogMgr.add(new LogVehicleEquip(
                player.getUserId(),
                userVehicle.getVehicleUid(),
                userVehicle.getTemplateId(),
                patronsId,
                1
        ));
    }

    public UserVehicle getEquipVehicle(int patronsId) {
        for (UserVehicle userVehicle : userVehicleMap.values()) {
            if (VehicleMgr.isUserVehicleExist(userVehicle)) {
                if (userVehicle.getPatronsId() == patronsId) {
                    return userVehicle;
                }
            }
        }
        return null;
    }

    public UserVehicleDetail getUserVehicleDetail() {
        return userVehicleDetail;
    }

    public UserVehicle getUserVehicle(String vehicleUid) {
        return userVehicleMap.get(vehicleUid);
    }

    //只有组合珍兽能用这个方法，因为只有一只
    public UserVehicle getUserCombVehicle(int templateId) {
        VehicleInfo vehicleInfo = VehicleMgr.getVehicleInfo(templateId);
        if (null == vehicleInfo) {
            return null;
        }
        if (vehicleInfo.getCombId() == 0) {
            log.error("err:使用了错误的方法");
            return null;
        }
        for (UserVehicle userVehicle : userVehicleMap.values()) {
            if (userVehicle.getTemplateId() == templateId) {
                return userVehicle;
            }
        }
        return null;
    }

    public UserVehicle getUserVehicleByPatrons(int patronsId) {
        if (null != userVehicleMap) {
            for (UserVehicle userVehicle : userVehicleMap.values()) {
                if (userVehicle.getPatronsId() == patronsId) {
                    return userVehicle;
                }
            }
        }
        return null;
    }

    private UserVehicle initUserVehicle(VehicleInfo vehicleInfo) {
        int templateId = vehicleInfo.getId();
        long nowTime = System.currentTimeMillis() / 1000;
        UserVehicle userVehicle = new UserVehicle();
        userVehicle.setUserId(player.getUserId());
        userVehicle.setVehicleUid(UUIDHelper.randomUUID(String.valueOf(GameServer.getInstance().getServerId())));
        userVehicle.setTemplateId(templateId);
        userVehicle.setPatronsId(0);
        userVehicle.setLevel(1);
        userVehicle.setBreakLv(0);
        userVehicle.setStudyLv(0);
        userVehicle.setEquipTimes(0);
        userVehicle.setEquipBuyTimes(0);
        userVehicle.setDelete(false);
        userVehicle.setCreateTime(nowTime);
        userVehicle.setLastUpdateTime(nowTime);
        if (vehicleInfo.getBonePowerSkill() > 0 && SystemOpenMgr.systemOpen(player, eSystemId.VehicleBone.getValue())) {
            userVehicle.setBoneLv(1);
            if (VehicleBoneConfigMgr.isHoleUnlock(1, 1)) {
                userVehicle.setBoneHole(1);
            }
        }
        userVehicle.setInsertOption();
        return userVehicle;
    }

    private UserVehicleSkill initUserVehicleSkill(String vehicleUid, int skillPos, VehicleSkillInfo randomSkill) {
        if (null == randomSkill) {
            return null;
        }
        UserVehicleSkill userVehicleSkill = new UserVehicleSkill();
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if(userVehicle != null){
            if(userVehicle.getSkillMap().containsKey(skillPos)){
                userVehicleSkill = userVehicle.getSkillMap().get(skillPos);
                userVehicleSkill.setInvalid(false);
                userVehicleSkill.setSkillType(randomSkill.getSkillType());
                userVehicleSkill.setValue(randomSkill.getValue());
                return userVehicleSkill;
            }
        }
        userVehicleSkill.setUserId(player.getUserId());
        userVehicleSkill.setVehicleUid(vehicleUid);
        userVehicleSkill.setSkillPos(skillPos);
        userVehicleSkill.setSkillType(randomSkill.getSkillType());
        userVehicleSkill.setValue(randomSkill.getValue());
        userVehicleSkill.setSkillModifyTimes(0);
        userVehicleSkill.setRandomSkillType(0);
        userVehicleSkill.setRandomValue(0);
        userVehicleSkill.setInsertOption();
        return userVehicleSkill;
    }

    private void onVehicleListChange(List<UserVehicle> userVehicleList) {
        for (UserVehicle userVehicle : userVehicleList) {
            onVehicleChange(userVehicle);
        }
    }

    /**
     * 座骑属性变化
     */
    public void onVehicleChange(UserVehicle userVehicle) {
        if (null == userVehicle) {
            return;
        }
        if (userVehicle.getPatronsId() > 0) {
            UserPatrons userPatrons = player.getModule(PatronsModule.class).getUserPatrons(userVehicle.getPatronsId());
            if (null != userPatrons) {
                player.getModule(PatronsModule.class).onPatronsChange(userPatrons);
            }
        }
        vehicleRankChange(userVehicle);
    }

    private void vehicleRankChange(UserVehicle userVehicle) {
        vehicleRankChange(userVehicle, false);
    }

    /**
     * 兽王苑榜单变化
     */
    private void vehicleRankChange(UserVehicle userVehicle, boolean isDelete) {

        if (!VehicleMgr.canJoinRank(userVehicle.getTemplateId())) {
            return;
        }

        if (isBestVehicleInType(userVehicle)) {

            // 赚钱值
            UserPatrons curPatrons = player.getModule(PatronsModule.class).getUserPatrons(userVehicle.getPatronsId());
            Map<Integer, UserVehicleSoul> userVehicleSoulMap = player.getModule(VehicleSoulModule.class).getUserVehicleSoulMap();
            Map<Integer, UserVehicleBone> userBoneMap = player.getModule(VehicleBoneModule.class).getAllEquipBoneMap();

            int curioAddition = 0;
            if(curPatrons == null){
                return;
            }
            PatronsInfo patronsInfo = PatronsMgr.getPatronsInfo(curPatrons.getPatronsId());
            if(patronsInfo != null){
                curioAddition = (int)CurioMgr.getSkillAdditionBySkillType(eSkillType.OccupationSoulStoneAddSkill.getValue(), player, patronsInfo.getOccupation());
            }

            int addition = (int) PatronsMgr.getVehicleAddition(curPatrons, userVehicleMap, userVehicleSoulMap, curioAddition, userBoneMap);

            // 技能
            JSONArray skillArray = new JSONArray();
            for (UserVehicleSkill skill : userVehicle.getSkillMapEffect().values()) {
                JSONObject skillObject = new JSONObject();
                skillObject.put("pos", skill.getSkillPos());
                skillObject.put("type", skill.getSkillType());
                skillObject.put("value", skill.getValue());
                skillArray.add(skillObject);
            }

            // 光环技能
            JSONArray otherSkillArray = VehicleMgr.getOtherSkillArray(userVehicle);

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("qualification", VehicleMgr.getVehicleQualification(userVehicle.getTemplateId(), userVehicle.getLevel()));
            jsonObject.put("addition", addition);
            jsonObject.put("skillList", skillArray);
            jsonObject.put("level", userVehicle.getLevel());
            jsonObject.put("otherSkillList", otherSkillArray);
            //兽魂的数据
            List<JSONObject> soulList = new ArrayList<>();
            for (UserVehicleSoul userVehicleSoul:userVehicleSoulMap.values()){
                if (userVehicleSoul.getVehicleId().equals(userVehicle.getVehicleUid())){
                    JSONObject soulData = new JSONObject();
                    soulData.put("soulId",userVehicleSoul.getSoulId());
                    soulData.put("id",userVehicleSoul.getConfigId());
                    soulData.put("occs",userVehicleSoul.getOccList());

                    List<JSONObject> entrys = new ArrayList<>();
                    if(userVehicleSoul.getEntryMap().size() > 0){
                        for(int index = 0;index < userVehicleSoul.getEntryMap().size();index++){
                            if(userVehicleSoul.getEntryMap().containsKey(index)){
                                List<Integer> infoList = userVehicleSoul.getEntryMap().get(index);
                                JSONObject entry = new JSONObject();
                                entry.put("occ",infoList.get(1));
                                entry.put("value",infoList.get(2));
                                entry.put("washTime",infoList.get(3));

                                entrys.add(entry);
                            }else{
                                break;
                            }
                        }
                    }
                    soulData.put("entrys",entrys);

                    JSONObject equip = new JSONObject();

                    equip.put("equipTime",userVehicleSoul.getEquipTime());
                    equip.put("pos",userVehicleSoul.getEquipPos());
                    equip.put("vehicleId",userVehicleSoul.getVehicleId());

                    soulData.put("equip",equip);


                    soulList.add(soulData);
                }
            }
            if (curPatrons != null){
                jsonObject.put("patronsId",curPatrons.getPatronsId());
            }else {
                jsonObject.put("patronsId",0);
            }

            jsonObject.put("soulList",soulList);
            jsonObject.put("soulBlockList",userVehicle.getSoulBlockList());

            RankMgr.changeUserRank(eBigRankType.Vehicle.getValue(), player.getUserId(),
                    isDelete ? BigInteger.valueOf(Long.MIN_VALUE) : BigInteger.valueOf(userVehicle.getStudyLv()), // 负数删除
                    userVehicle.getTemplateId(), jsonObject.toJSONString());
        }
    }

    /**
     * 是否是该类型最优珍兽
     */
    private boolean isBestVehicleInType(UserVehicle userVehicle) {
        for (UserVehicle vehicle : userVehicleMap.values()) {
            if (vehicle.isDelete() ||
                    vehicle.getTemplateId() != userVehicle.getTemplateId() ||
                    vehicle.getVehicleUid().equals(userVehicle.getVehicleUid())) {
                continue;
            }
            // 觉醒值
            if (vehicle.getStudyLv() != userVehicle.getStudyLv()) {
                if (vehicle.getStudyLv() > userVehicle.getStudyLv()) {
                    return false;
                }
                continue;
            }
            // 赚钱值
            Map<Integer, UserVehicleSoul> userVehicleSoulMap = player.getModule(VehicleSoulModule.class).getUserVehicleSoulMap();
            Map<Integer, UserVehicleBone> userBoneMap = player.getModule(VehicleBoneModule.class).getAllEquipBoneMap();
            double curAddi = PatronsMgr.getVehicleAddition(player.getModule(PatronsModule.class).getUserPatrons(userVehicle.getPatronsId()), userVehicleMap, userVehicleSoulMap, 0, userBoneMap);
            double otherAddi = PatronsMgr.getVehicleAddition(player.getModule(PatronsModule.class).getUserPatrons(vehicle.getPatronsId()), userVehicleMap, userVehicleSoulMap, 0, userBoneMap);
            if (otherAddi != curAddi) {
                if (otherAddi > curAddi) {
                    return false;
                }
                continue;
            }
        }
        return true;
    }

    /**
     * 获取排行榜珍兽
     */
    private Map<Integer, UserVehicle> getBestRankVehicleMap() {
        Map<Integer, UserVehicle> rankVehicleMap = new ConcurrentHashMap<>();
        for (UserVehicle userVehicle : userVehicleMap.values()) {
            // 删除的不考虑
            if (userVehicle.isDelete()) {
                continue;
            }
            // 跳过非排行榜珍兽类型
            if (!VehicleMgr.canJoinRank(userVehicle.getTemplateId())) {
                continue;
            }
            // 第一只直接加入
            if (!rankVehicleMap.containsKey(userVehicle.getTemplateId())) {
                rankVehicleMap.put(userVehicle.getTemplateId(), userVehicle);
                continue;
            }
            // 已有的，比较属性
            UserVehicle lastVehicle = rankVehicleMap.get(userVehicle.getTemplateId());
            // 比较觉醒值
            if (lastVehicle.getStudyLv() != userVehicle.getStudyLv()) {
                if (lastVehicle.getStudyLv() < userVehicle.getStudyLv()) {
                    rankVehicleMap.put(userVehicle.getTemplateId(), userVehicle);
                }
                continue;
            }
            Map<Integer, UserVehicleSoul> userVehicleSoulMap = player.getModule(VehicleSoulModule.class).getUserVehicleSoulMap();
            Map<Integer, UserVehicleBone> userBoneMap = player.getModule(VehicleBoneModule.class).getAllEquipBoneMap();
            // 比较赚钱值
            double curAddi = PatronsMgr.getVehicleAddition(player.getModule(PatronsModule.class).getUserPatrons(userVehicle.getPatronsId()), userVehicleMap,userVehicleSoulMap, 0, userBoneMap);
            double lastAddi = PatronsMgr.getVehicleAddition(player.getModule(PatronsModule.class).getUserPatrons(lastVehicle.getPatronsId()), userVehicleMap,userVehicleSoulMap, 0, userBoneMap);
            if (lastAddi != curAddi) {
                if (lastAddi < curAddi) {
                    rankVehicleMap.put(userVehicle.getTemplateId(), userVehicle);
                }
                continue;
            }
        }
        return rankVehicleMap;
    }

    public boolean canMountVehicle(String vehicleUid, int patronsId) {
        PatronsVehicleBindingData bindingData = patronsVehicleBindingDataMap.get(vehicleUid);
        if (bindingData == null) {
            return true;
        }
        if (bindingData.getPatronsId() == patronsId || bindingData.getPatronsId() == 0) {
            return true;
        }

        if (DateHelper.getCurrentSecond() >= bindingData.getSystemEndTime()) {
            bindingData.setPatronsId(0);
            return true;
        }

        return false;
    }

    /**
     * 是否可以卸载魂骨
     */
    public boolean canUnMountVehicleBone(String vehicleUid, int boneId) {
        PatronsVehicleBindingData bindingData = patronsVehicleBindingDataMap.get(vehicleUid);
        if (bindingData != null) {
            if(!bindingData.getActivityIdList().isEmpty()) {
                return false;
            }
            if(bindingData.getSystemEndTime() >= DateHelper.getCurrentSecond()){
                return false;
            }
        }
        return true;
    }

    /**
     * 珍兽技能改装自动化
     *
     * @param vehicleUid  珍兽id
     * @param skillType   技能职业类型
     * @param skillPos    技能位置
     * @param isCustomize 是否定制
     * @param goalVal     目标值
     * @param costLimit   消耗限制
     */
    public VehicleModifySkillResult modifyVehicleSkillAuto(String vehicleUid, int skillType, int skillPos, boolean isCustomize, long goalVal, String costLimit, boolean isBegin) {
        if (isBegin) {
            playerVehicleAutoModifyCost.clear();
        }
        VehicleModifySkillResult res = new VehicleModifySkillResult();
        if (player.getTitleId() < GameConfig.VEHICLE_SKILL_ONE_KEY_MODIFY_NEED_TITLE) {
            res.setRet(GameErrorCode.E_TITLE_LEVEL_NO_ENOUGH);
            return res;
        }
        //目标限制
        UserVehicle userVehicle = getUserVehicle(vehicleUid);
        if (!VehicleMgr.isUserVehicleExist(userVehicle)) {
            res.setRet(GameErrorCode.E_VEHICLE_NO_FOUND);
            return res;
        }
        UserVehicleSkill vehicleSkill = userVehicle.getSkillMapEffect().get(skillPos);
        if (vehicleSkill == null) {
            res.setRet(GameErrorCode.E_VEHICLE_SKILL_NO_FOUND);
            return res;
        }
        res.setVehicleSkill(vehicleSkill);
        if (vehicleSkill.getSkillType() == skillType && vehicleSkill.getValue() >= goalVal) {
            res.setRet(GameErrorCode.E_VEHICLE_SKILL_VALUE_LIMIT);
            return res;
        }
        //消耗限制
        if (!isCustomize) {
            BigInteger silver = VehicleMgr.getModifySkillCost(vehicleSkill.getSkillModifyTimes());
            if (silver.compareTo(new BigInteger(costLimit)) > 0) {
                res.setRet(GameErrorCode.E_VEHICLE_SKILL_MODIFY_COST_LIMIT);
                return res;
            }
        }
        //改装
        VehicleModifySkillResult modifyResult = randomSkill(vehicleUid, skillPos, isCustomize, true);
        //替换
        if (modifyResult.getRet() == 0 && modifyResult.getVehicleSkill().getRandomSkillType() == skillType) {
            if (modifyResult.getVehicleSkill().getSkillType() == skillType && modifyResult.getVehicleSkill().getRandomValue() <= modifyResult.getVehicleSkill().getValue()) {
                return modifyResult;
            }
            modifyResult.setReplace(true);
            agreeModifySkill(vehicleUid, skillPos);
        }
        return modifyResult;
    }

    public void stopVehicleSkillModifyAuto(VehicleProto.StopVehicleSkillModifyAutoRespMsg.Builder respMsg) {
        Property cost = new Property();
        cost.addProperty(GameConfig.VEHICLE_SKILL_CUSTOM_MODIFY_ITEM, BigInteger.valueOf(playerVehicleAutoModifyCost.getItemCost()));
        cost.addProperty(GameConfig.GAME_MONEY_SILVER, BigInteger.valueOf(playerVehicleAutoModifyCost.getSliverCost()));
        respMsg.setCost(PropertyHelper.parsePropertyToString(cost));
        playerVehicleAutoModifyCost.clear();
    }
    public void bindPatrons(int patronsId, int activityId) {
        UserVehicle userVehicleByPatrons = getUserVehicleByPatrons(patronsId);
        if (userVehicleByPatrons != null) {
            addPatronsBindData(activityId,patronsId,userVehicleByPatrons.getVehicleUid());
        }

        ManorFishPondModel fishPondModel = player.getModule(ManorModule.class).getManorFishPondModel();
        if (fishPondModel != null) {
            FishData fishData = FishPondMgr.getUserFishByPatrons(patronsId, fishPondModel.getFishDataMap());
            if (fishData != null) {
                fishPondModel.addPatronsBindData(activityId, patronsId, fishData.getFishId());
            }
        }

        //蛐蛐
        CricketModule cricketModule = player.getModule(CricketModule.class);
        CricketData cricketData = CricketMgr.getUserCricketByPatrons(patronsId, cricketModule.getCricketDataMap());
        if (cricketData != null) {
            cricketModule.addPatronsBindData(activityId, patronsId, cricketData.getCricketId());
        }
    }

    public void bindPatronsSystem(int patronsId, int systemId, long endTime) {
        UserVehicle userVehicleByPatrons = getUserVehicleByPatrons(patronsId);
        if (userVehicleByPatrons != null) {
            addPatronsBindSystem(systemId, patronsId, userVehicleByPatrons.getVehicleUid(), endTime);
        }

        ManorFishPondModel fishPondModel = player.getModule(ManorModule.class).getManorFishPondModel();
        if (fishPondModel != null) {
            FishData fishData = FishPondMgr.getUserFishByPatrons(patronsId, fishPondModel.getFishDataMap());
            if (fishData != null) {
                fishPondModel.addPatronsBindSystem(systemId, patronsId, fishData.getFishId(), endTime);
            }
        }

        //蛐蛐
        CricketModule cricketModule = player.getModule(CricketModule.class);
        CricketData cricketData = CricketMgr.getUserCricketByPatrons(patronsId, cricketModule.getCricketDataMap());
        if (cricketData != null) {
            cricketModule.addPatronsBindSystem(systemId, patronsId, cricketData.getCricketId(), endTime);
        }
    }

    public boolean isRecycleLock() {
        if (ChannelConfig.VEHICLE_RECYCLE_LOCK == 0) {
            return false;
        }
        if (null == userPassword) {
            return false;
        }

        if (!StringUtils.isNullOrEmpty(userPassword.getRecyclePassword())) {
            return true;
        }

        if (userPassword.getLockRecycleEndTime() > DateHelper.getCurrentTime()) {
            return true;
        }

        return false;
    }

    /**
     * 设置回收密码
     *
     * @param reqMsg RecyclePassWordSetReqMsg
     * @return RecyclePassWordRespMsg.Builder
     */
    public VehicleProto.RecyclePassWordRespMsg.Builder setRecyclePassWord(VehicleProto.RecyclePassWordSetReqMsg reqMsg) {
        VehicleProto.RecyclePassWordRespMsg.Builder respMsg = VehicleProto.RecyclePassWordRespMsg.newBuilder();
        respMsg.setRet(0);

        if (ChannelConfig.VEHICLE_RECYCLE_LOCK == 0) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_PASSWORD_CLOSE);
        }

        if (isRecycleLock()) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_LOCK);
        }

        //二级密码需设置为6位纯数字
        Integer lengthMin = 6;
        Integer lengthMax = 6;
        List<Integer> wordLength = StringUtils.stringToIntegerList(GameConfig.RECYCLE_PASSWORD_LENGTH, "-");
        if (wordLength.size() == 2) {
            lengthMin = wordLength.get(0);
            lengthMax = wordLength.get(1);
        }
        if (!ForbiddenWordMgr.checkPassWordFormat(reqMsg.getNewPassWord(), lengthMin, lengthMax)) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_PASSWORD_FORMAT_WRONG);
        }

        if (null == userPassword) {
            UserPassword uesrPassword = new UserPassword();
            uesrPassword.setUserId(player.getUserId());
            uesrPassword.setRecyclePassword(reqMsg.getNewPassWord());
            uesrPassword.setInsertOption();
            userPassword = uesrPassword;
        } else {
            userPassword.setRecyclePassword(reqMsg.getNewPassWord());
        }
        userPassword.setLockRecycleEndTime(0);

        respMsg.setStatusInfo(VehiclePb.buildRecycleLockStatusMsg(userPassword));

        return respMsg;
    }

    /**
     * 验证回收密码
     *
     * @param reqMsg RecyclePassWordVerifyReqMsg
     * @return RecyclePassWordRespMsg.Builder
     */
    public VehicleProto.RecyclePassWordRespMsg.Builder verifyRecyclePassWord(VehicleProto.RecyclePassWordVerifyReqMsg reqMsg) {
        VehicleProto.RecyclePassWordRespMsg.Builder respMsg = VehicleProto.RecyclePassWordRespMsg.newBuilder();
        respMsg.setRet(0);
        if (ChannelConfig.VEHICLE_RECYCLE_LOCK == 0) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_PASSWORD_CLOSE);
        }
        if (!isRecycleLock()) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_UNLOCK);
        }

        if (!userPassword.getRecyclePassword().equals(reqMsg.getCheckPassWord())) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_PASSWORD_WRONG);
        }

        if (null != userPassword) {
            userPassword.setRecyclePassword("");
            userPassword.setLockRecycleEndTime(0);
        }

        respMsg.setStatusInfo(VehiclePb.buildRecycleLockStatusMsg(userPassword));

        return respMsg;
    }

    /**
     * 强行解除放归保护
     */
    public VehicleProto.ForciblyCancelRecycleLockRespMsg.Builder forciblyCancelRecycleLock() {
        VehicleProto.ForciblyCancelRecycleLockRespMsg.Builder respMsg = VehicleProto.ForciblyCancelRecycleLockRespMsg.newBuilder();
        respMsg.setRet(0);
        if (ChannelConfig.VEHICLE_RECYCLE_LOCK == 0) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_PASSWORD_CLOSE);
        }
        if (!isRecycleLock()) {
            return respMsg.setRet(GameErrorCode.E_VEHICLE_RECYCLE_UNLOCK);
        }

        if (null != userPassword) {
            userPassword.setRecyclePassword("");
            userPassword.setLockRecycleEndTime(DateHelper.getCurrentTime() + GameConfig.RECYCLE_LOCK_END_TIME_SECONDS * 1000);
        }

        respMsg.setStatusInfo(VehiclePb.buildRecycleLockStatusMsg(userPassword));
        return respMsg;
    }

    public void sendVehicleRecycleLock() {
        player.sendPacket(Protocol.U_VEHICLE_RECYCLE_LOCK_STATUS, VehiclePb.buildRecycleLockStatusMsg(userPassword));
    }

    public int getSkillAddition(int type, int param) {
        return SkillMgr.getSkillAdditionFromMap(type, param, SkillMgr.initVehicleTalentSkillAdditionMap(userVehicleMap));
    }

    /**
     * 获取自动放归列表
     */
    public void getAutoRecycleList() {
        VehicleProto.VehicleGetAutoRecycleListRespMsg.Builder resp = VehicleProto.VehicleGetAutoRecycleListRespMsg.newBuilder();

        resp.setEnableAutoRecycle(userVehicleDetail.isEnableAutoRecycle());
        resp.addAllVehicleId(userVehicleDetail.getAutoRecycleList());

        player.sendPacket(Protocol.U_VEHICLE_GET_AUTO_RECYCLE_LIST, resp);
    }

    /**
     * 设置自动放归列表
     *
     * @param vehicleIds 自动放归列表
     * @return ret
     */
    public int setAutoRecycleList(boolean enableAutoRecycle, List<Integer> vehicleIds) {
        for (int id : vehicleIds) {
            if (!GoodsMgr.isVehicleGoods(id)) {
                return GameErrorCode.E_VEHICLE_NO_FOUND;
            }
        }

        userVehicleDetail.setEnableAutoRecycle(enableAutoRecycle);
        userVehicleDetail.setAutoRecycleList(vehicleIds);
        player.sendPacket(Protocol.U_VEHICLE_SET_AUTO_RECYCLE_LIST, VehicleProto.VehicleSetAutoRecycleListRespMsg.newBuilder().setRet(0));

        return 0;
    }

    private void addRecycleVehicleUID(String vehicleUID) {
        synchronized (recycleVehicleUIDs) {
            recycleVehicleUIDs.add(vehicleUID);
        }
    }

    private List<String> popAllRecycleVehicleUID() {
        List<String> tmpList;
        if (recycleVehicleUIDs.isEmpty()) {
            return new ArrayList<>();
        }
        synchronized (recycleVehicleUIDs) {
            tmpList = new ArrayList<>(recycleVehicleUIDs);
            recycleVehicleUIDs.clear();
        }

        return tmpList;
    }

    public void finishChanges() {
        List<String> tmpList = popAllRecycleVehicleUID();
        if (!tmpList.isEmpty()) {
            VehicleRecycleResult result = vehicleRecycle(tmpList, true);
            if (null != result) {
                VehicleProto.VehicleRecycleRespMsg.Builder respMsg = VehicleProto.VehicleRecycleRespMsg.newBuilder();
                respMsg.setRet(result.getRet());
                if (0 == result.getRet()) {
                    respMsg.addAllVehicleUid(result.getRecycleVehicleUidList());
                    respMsg.setRewards(result.getRecycleReward());
                    respMsg.setVehicles(result.getRecycleVehicleStr());
                }
                player.sendPacket(Protocol.U_VEHICLE_RECYCLE, respMsg);
            } else {
                log.error("userId:{} VehicleRecycleResult 为空 recycleVehicleUIDs：{}", getUserId(), tmpList.toString());
            }
        }
    }
}
